A, B, and C

  1. Get the raw data from the Google Books NGram Viewer website (http://storage.googleapis.com/books/ngrams/books/datasetsv2.html). In particular, you should use version 2 of the English language corpus, which was released on July 1, 2012. Uncompressed, this file is 1.4 GB.
  2. Recreate the main part of figure 3a of Michel et al. (2011). To recreate this figure, you will need two files: the one you downloaded in part (a) and the “total counts” file, which you can use to convert the raw counts into proportions. Note that the total counts file has a structure that may make it a bit hard to read in. Does version 2 of the NGram data produce similar results to those presented in Michel et al. (2011), which are based on version 1 data?
  3. Now check your graph against the graph created by the NGram Viewer (https://books.google.com/ngrams).

Load the 1gram file

install.packages("tidyverse")
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.5/tidyverse_1.2.1.tgz'
Content type 'application/x-gzip' length 88754 bytes (86 KB)
==================================================
downloaded 86 KB

The downloaded binary packages are in
    /var/folders/fb/p2xy06255856sb5hx3143jdr0000gn/T//RtmpNEl8cw/downloaded_packages
library(tidyverse)
── Attaching packages ─────────────────────────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 3.1.0     ✔ purrr   0.2.5
✔ tibble  2.0.1     ✔ dplyr   0.7.8
✔ tidyr   0.8.2     ✔ stringr 1.4.0
✔ readr   1.3.1     ✔ forcats 0.3.0
── Conflicts ────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
setwd("~/Desktop/Project 1")
getwd()
[1] "/Users/KangBangg/Desktop/Project 1"

Filter by the three years I want: 1883, 1910, and 1950

ngram = ngram %>% rename(
  word = V1,
  year = V2,
  match_count = V3,
  volume_count = V4
  )
ngram1 = filter(ngram, word == "1883" | word == "1910" | word == "1950")
ngram1

Load the total count file

totalcount = read.table("totalcount.txt", sep = "\t", colClasses = "character")
totalcount

The current format of this is (year, match_count, page_count, volume_count). I have to make them into 4 columns. Use the separate function

totalcount = separate_rows(totalcount, V1:V425, convert = TRUE)
rownames(totalcount)[1] = "year"
rownames(totalcount)[2] = "match_count"
rownames(totalcount)[3] = "page_count"
rownames(totalcount)[4] = "volume_count"
finaltotalcount = as.data.frame(t(totalcount))
finaltotalcount

Take the match_count of ngram1 and divide it by the match_count of finaltotalcount to find the proportion of the ngram compared to total words used for that year.

figurea1 = select(ngram1,
                 word,
                 year,
                 match_count)
figurea2 = select(finaltotalcount,
                  year,
                  match_count)
figurea3 = left_join(figurea1, figurea2, by = "year") %>%
  mutate(frequency = match_count.x / match_count.y)
figurea3

Make the vizualization

ggplot(figurea3, aes(x = year, y = frequency, colour = word)) +
  geom_freqpoly(binwidth = 500, stat = "identity")
Ignoring unknown parameters: binwidth

D

  1. Recreate figure 3a (main figure), but change the y-axis to be the raw mention count (not the rate of mentions).

Raw count vizualization

ggplot(figurea3, aes(x = year, y = match_count.x , colour = word)) +
  geom_freqpoly(binwidth = 500, stat = "identity")
Ignoring unknown parameters: binwidth

E

  1. Does the difference between (b) and (d) lead you to reevaluate any of the results of Michel et al. (2011).Why or why not?

The way Michel used frequency to determine word use decay makes sense as overtime more words will be added to the corpus and the amount of word mentions over time could increase due to possible reasons as more people, more authors, better document collection, and more outlets to use such as social media. If Michel and other were to rely on the raw mention count overtime, he may of thought word use increases over time, but that is not the case.

F

  1. Now, using the proportion of mentions, replicate the inset of figure 3a. That is, for each year between 1875 and 1975, calculate the half-life of that year. The half-life is defined to be the number of years that pass before the proportion of mentions reaches half its peak value. Note that Michel et al. (2011) do something more complicated to estimate the halflife— see section III.6 of their Supporting Online Information—but they claim that both approaches produce similar results. Does version 2 of the NGram data produce similar results to those presented in Michel et al. (2011), which are based on version 1 data? (Hint: Don’t be surprised if it doesn’t.)

Half-life calculation

ngram$word = as.integer(ngram$word)
hlNgram = filter(ngram, word >= 1875)
hlNgramf = filter(hlNgram, word <= 1975)
originalhl = left_join(hlNgramf, figurea2, by = "year") %>%
  mutate(frequency = match_count.x / match_count.y) %>%
  select(word, year, frequency) %>%
  mutate(yearG = year > word) %>%
  filter(yearG == TRUE)
hl = originalhl

After find the max frequency for each year and then filter frequency by 1/2 the max. Afterwards subtract the 1/2 frequency by the max.

hlM = originalhl %>% group_by(word) %>% summarise(frequency = max(frequency))
hlY = originalhl %>% group_by(year) 
hlT = left_join(hlM, hlY, by = "frequency", suffix = c(".x", ".y"))
hlT = select(hlT, word.x, year, frequency)
hlT = hlT %>% group_by(word.x) %>% filter (! duplicated(word.x)) %>%
  rename(word = word.x)
hlT2 = hlT %>% select(frequency) %>%
  left_join(hl, hlT, by = "word") %>%
  filter(frequency.x > (frequency.y / 2)) %>%
  select(word, frequency.x, year)


hlF = left_join(hlT, hlT2, by = "word") %>%
  filter(year.y > year.x) %>%
  group_by(word) %>% summarise(year.y = min(year.y))
hlT = hlT %>% select(word, year)
hlF = left_join(hlF, hlT, by = "word") 
hlF = mutate(hlF, half_life = (year.y - year))
hlF = hlF %>% rename(ngram_year = word)
hlF = hlF %>% select(ngram_year, half_life)
hlF

Make the half-life vizualization.

Does version 2 of the NGram data produce similar results to those presented in Michel et al. (2011), which are based on version 1 data? (Hint: Don’t be surprised if it doesn’t.) It does not as in Michel et al. their half life values for early years of the range 1875-1975 start off extremely high at 30 and then curve down later in the year range to an average of 15 years for half-life.

G

  1. Were there any years that were outliers, such as years that were forgotten particularly quickly or particularly slowly? Briefly speculate about possible reasons for that pattern and explain how you identified the outliers. Any years with a half-life > 10 would be an outlier and I determined that by using geom_smooth which applies a conditional mean line onto the ggplot. The most likely explanation for these outliers is historical events that happened such as wars or tragedies. For the year 1912 it had a half-life of 26, looking at the events of that year, there was the tragic event of the Titanic sinking. However what is strange is if my guess were to be true, that would mean the year 1914 which is the start of WW1, would have a high half-life. Looking at it, it does not and looking at the end year of WW1, 1918, it has a half-life of 1 with a peak rate of mentions in 1921.

H

  1. Now replicate this result for version 2 of the NGrams data in Chinese, French, German, Hebrew, Italian, Russian and Spanish.

Chinese

French

German

Hebrew

Italian

Russian

Spanish

I

  1. Comparing across all languages, were there any years that were outliers, such as years that were forgotten particularly quickly or particularly slowly? Briefly speculate about possible reasons for that pattern.

Across all languages, there are outliers within the middle of the range of 1875-1975, specifically the 1gram 1925, my speculation would be that these are years with international events that were recorded in each language and there would be a high frequency of them with a high half-life due to the importance of those events that happened within those years. Looking at Hebrew, Chinese and Italian, they both have their largest outlier in 2 years close to each other which could be a shared event among them. China has a higher variance around its 1gram half-life frequency out of every other language between 1875-1925 which could be due to sociopolitical events within mandarin/cantonese speaking areas.

LS0tCnRpdGxlOiAiUHJvamVjdDEgQml0IGJ5IEJpdCAyLjciCkF1dGhvcjogIlNhbXVlbCBLYW5nIgpkYXRlOiAiMDIuMTUuMTkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiNBLCBCLCBhbmQgQwphKSBHZXQgdGhlIHJhdyBkYXRhIGZyb20gdGhlIEdvb2dsZSBCb29rcyBOR3JhbSBWaWV3ZXIgd2Vic2l0ZQooaHR0cDovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vYm9va3MvbmdyYW1zL2Jvb2tzL2RhdGFzZXRzdjIuaHRtbCkuIEluCnBhcnRpY3VsYXIsIHlvdSBzaG91bGQgdXNlIHZlcnNpb24gMiBvZiB0aGUgRW5nbGlzaCBsYW5ndWFnZSBjb3JwdXMsIHdoaWNoCndhcyByZWxlYXNlZCBvbiBKdWx5IDEsIDIwMTIuIFVuY29tcHJlc3NlZCwgdGhpcyBmaWxlIGlzIDEuNCBHQi4KYikgUmVjcmVhdGUgdGhlIG1haW4gcGFydCBvZiBmaWd1cmUgM2Egb2YgTWljaGVsIGV0IGFsLiAoMjAxMSkuIFRvIHJlY3JlYXRlCnRoaXMgZmlndXJlLCB5b3Ugd2lsbCBuZWVkIHR3byBmaWxlczogdGhlIG9uZSB5b3UgZG93bmxvYWRlZCBpbiBwYXJ0IChhKQphbmQgdGhlIOKAnHRvdGFsIGNvdW50c+KAnSBmaWxlLCB3aGljaCB5b3UgY2FuIHVzZSB0byBjb252ZXJ0IHRoZSByYXcgY291bnRzCmludG8gcHJvcG9ydGlvbnMuIE5vdGUgdGhhdCB0aGUgdG90YWwgY291bnRzIGZpbGUgaGFzIGEgc3RydWN0dXJlIHRoYXQgbWF5Cm1ha2UgaXQgYSBiaXQgaGFyZCB0byByZWFkIGluLiBEb2VzIHZlcnNpb24gMiBvZiB0aGUgTkdyYW0gZGF0YSBwcm9kdWNlCnNpbWlsYXIgcmVzdWx0cyB0byB0aG9zZSBwcmVzZW50ZWQgaW4gTWljaGVsIGV0IGFsLiAoMjAxMSksIHdoaWNoIGFyZSBiYXNlZApvbiB2ZXJzaW9uIDEgZGF0YT8KYykgTm93IGNoZWNrIHlvdXIgZ3JhcGggYWdhaW5zdCB0aGUgZ3JhcGggY3JlYXRlZCBieSB0aGUgTkdyYW0gVmlld2VyCihodHRwczovL2Jvb2tzLmdvb2dsZS5jb20vbmdyYW1zKS4KCgpMb2FkIHRoZSAxZ3JhbSBmaWxlCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKc2V0d2QoIn4vRGVza3RvcC9Qcm9qZWN0IDEiKQpnZXR3ZCgpCm5ncmFtb3JpZ2luYWwgPSByZWFkLnRhYmxlKCIxZ3JhbS50eHQiKQpuZ3JhbSA9IG5ncmFtb3JpZ2luYWwKYGBgCgoKRmlsdGVyIGJ5IHRoZSB0aHJlZSB5ZWFycyBJIHdhbnQ6IDE4ODMsIDE5MTAsIGFuZCAxOTUwCmBgYHtyfQpuZ3JhbSA9IG5ncmFtICU+JSByZW5hbWUoCiAgd29yZCA9IFYxLAogIHllYXIgPSBWMiwKICBtYXRjaF9jb3VudCA9IFYzLAogIHZvbHVtZV9jb3VudCA9IFY0CiAgKQpuZ3JhbTEgPSBmaWx0ZXIobmdyYW0sIHdvcmQgPT0gIjE4ODMiIHwgd29yZCA9PSAiMTkxMCIgfCB3b3JkID09ICIxOTUwIikKbmdyYW0xCmBgYAoKCgpMb2FkIHRoZSB0b3RhbCBjb3VudCBmaWxlCmBgYHtyfQp0b3RhbGNvdW50ID0gcmVhZC50YWJsZSgidG90YWxjb3VudC50eHQiLCBzZXAgPSAiXHQiLCBjb2xDbGFzc2VzID0gImNoYXJhY3RlciIpCnRvdGFsY291bnQKYGBgCgoKVGhlIGN1cnJlbnQgZm9ybWF0IG9mIHRoaXMgaXMgKHllYXIsIG1hdGNoX2NvdW50LCBwYWdlX2NvdW50LCB2b2x1bWVfY291bnQpLiBJIGhhdmUgdG8gbWFrZSB0aGVtIGludG8gNCBjb2x1bW5zLiBVc2UgdGhlIHNlcGFyYXRlIGZ1bmN0aW9uCmBgYHtyfQp0b3RhbGNvdW50ID0gc2VwYXJhdGVfcm93cyh0b3RhbGNvdW50LCBWMTpWNDI1LCBjb252ZXJ0ID0gVFJVRSkKcm93bmFtZXModG90YWxjb3VudClbMV0gPSAieWVhciIKcm93bmFtZXModG90YWxjb3VudClbMl0gPSAibWF0Y2hfY291bnQiCnJvd25hbWVzKHRvdGFsY291bnQpWzNdID0gInBhZ2VfY291bnQiCnJvd25hbWVzKHRvdGFsY291bnQpWzRdID0gInZvbHVtZV9jb3VudCIKZmluYWx0b3RhbGNvdW50ID0gYXMuZGF0YS5mcmFtZSh0KHRvdGFsY291bnQpKQpmaW5hbHRvdGFsY291bnQKYGBgCgoKVGFrZSB0aGUgbWF0Y2hfY291bnQgb2YgbmdyYW0xIGFuZCBkaXZpZGUgaXQgYnkgdGhlIG1hdGNoX2NvdW50IG9mIGZpbmFsdG90YWxjb3VudCB0byBmaW5kIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBuZ3JhbSBjb21wYXJlZCB0byB0b3RhbCB3b3JkcyB1c2VkIGZvciB0aGF0IHllYXIuIApgYGB7cn0KZmlndXJlYTEgPSBzZWxlY3QobmdyYW0xLAogICAgICAgICAgICAgICAgIHdvcmQsCiAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICBtYXRjaF9jb3VudCkKZmlndXJlYTIgPSBzZWxlY3QoZmluYWx0b3RhbGNvdW50LAogICAgICAgICAgICAgICAgICB5ZWFyLAogICAgICAgICAgICAgICAgICBtYXRjaF9jb3VudCkKCmZpZ3VyZWEzID0gbGVmdF9qb2luKGZpZ3VyZWExLCBmaWd1cmVhMiwgYnkgPSAieWVhciIpICU+JQogIG11dGF0ZShmcmVxdWVuY3kgPSBtYXRjaF9jb3VudC54IC8gbWF0Y2hfY291bnQueSkKZmlndXJlYTMKYGBgCgoKCk1ha2UgdGhlIHZpenVhbGl6YXRpb24gCmBgYHtyfQpnZ3Bsb3QoZmlndXJlYTMsIGFlcyh4ID0geWVhciwgeSA9IGZyZXF1ZW5jeSwgY29sb3VyID0gd29yZCkpICsKICBnZW9tX2ZyZXFwb2x5KGJpbndpZHRoID0gNTAwLCBzdGF0ID0gImlkZW50aXR5IikKYGBgCgoKI0QKZCkgUmVjcmVhdGUgZmlndXJlIDNhIChtYWluIGZpZ3VyZSksIGJ1dCBjaGFuZ2UgdGhlIHktYXhpcyB0byBiZSB0aGUgcmF3Cm1lbnRpb24gY291bnQgKG5vdCB0aGUgcmF0ZSBvZiBtZW50aW9ucykuCgoKUmF3IGNvdW50IHZpenVhbGl6YXRpb24gCmBgYHtyfQpnZ3Bsb3QoZmlndXJlYTMsIGFlcyh4ID0geWVhciwgeSA9IG1hdGNoX2NvdW50LnggLCBjb2xvdXIgPSB3b3JkKSkgKwogIGdlb21fZnJlcXBvbHkoYmlud2lkdGggPSA1MDAsIHN0YXQgPSAiaWRlbnRpdHkiKQpgYGAKCgojRQplKSBEb2VzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gKGIpIGFuZCAoZCkgbGVhZCB5b3UgdG8gcmVldmFsdWF0ZSBhbnkgb2YgdGhlCnJlc3VsdHMgb2YgTWljaGVsIGV0IGFsLiAoMjAxMSkuV2h5IG9yIHdoeSBub3Q/CgogIFRoZSB3YXkgTWljaGVsIHVzZWQgZnJlcXVlbmN5IHRvIGRldGVybWluZSB3b3JkIHVzZSBkZWNheSBtYWtlcyBzZW5zZSBhcyBvdmVydGltZSBtb3JlIHdvcmRzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGNvcnB1cyBhbmQgdGhlIGFtb3VudCBvZiB3b3JkIG1lbnRpb25zIG92ZXIgdGltZSBjb3VsZCBpbmNyZWFzZSBkdWUgdG8gcG9zc2libGUgcmVhc29ucyBhcyBtb3JlIHBlb3BsZSwgbW9yZSBhdXRob3JzLCBiZXR0ZXIgZG9jdW1lbnQgY29sbGVjdGlvbiwgYW5kIG1vcmUgb3V0bGV0cyB0byB1c2Ugc3VjaCBhcyBzb2NpYWwgbWVkaWEuIElmIE1pY2hlbCBhbmQgb3RoZXIgd2VyZSB0byByZWx5IG9uIHRoZSByYXcgbWVudGlvbiBjb3VudCBvdmVydGltZSwgaGUgbWF5IG9mIHRob3VnaHQgd29yZCB1c2UgaW5jcmVhc2VzIG92ZXIgdGltZSwgYnV0IHRoYXQgaXMgbm90IHRoZSBjYXNlLiAKICAKCiNGCmYpIE5vdywgdXNpbmcgdGhlIHByb3BvcnRpb24gb2YgbWVudGlvbnMsIHJlcGxpY2F0ZSB0aGUgaW5zZXQgb2YgZmlndXJlIDNhLgpUaGF0IGlzLCBmb3IgZWFjaCB5ZWFyIGJldHdlZW4gMTg3NSBhbmQgMTk3NSwgY2FsY3VsYXRlIHRoZSBoYWxmLWxpZmUgb2YKdGhhdCB5ZWFyLiBUaGUgaGFsZi1saWZlIGlzIGRlZmluZWQgdG8gYmUgdGhlIG51bWJlciBvZiB5ZWFycyB0aGF0IHBhc3MKYmVmb3JlIHRoZSBwcm9wb3J0aW9uIG9mIG1lbnRpb25zIHJlYWNoZXMgaGFsZiBpdHMgcGVhayB2YWx1ZS4gTm90ZSB0aGF0Ck1pY2hlbCBldCBhbC4gKDIwMTEpIGRvIHNvbWV0aGluZyBtb3JlIGNvbXBsaWNhdGVkIHRvIGVzdGltYXRlIHRoZSBoYWxmbGlmZeKAlApzZWUgc2VjdGlvbiBJSUkuNiBvZiB0aGVpciBTdXBwb3J0aW5nIE9ubGluZSBJbmZvcm1hdGlvbuKAlGJ1dCB0aGV5CmNsYWltIHRoYXQgYm90aCBhcHByb2FjaGVzIHByb2R1Y2Ugc2ltaWxhciByZXN1bHRzLiBEb2VzIHZlcnNpb24gMiBvZiB0aGUKTkdyYW0gZGF0YSBwcm9kdWNlIHNpbWlsYXIgcmVzdWx0cyB0byB0aG9zZSBwcmVzZW50ZWQgaW4gTWljaGVsIGV0IGFsLgooMjAxMSksIHdoaWNoIGFyZSBiYXNlZCBvbiB2ZXJzaW9uIDEgZGF0YT8gKEhpbnQ6IERvbuKAmXQgYmUgc3VycHJpc2VkIGlmIGl0CmRvZXNu4oCZdC4pCgoKSGFsZi1saWZlIGNhbGN1bGF0aW9uCgpgYGB7cn0KbmdyYW0kd29yZCA9IGFzLmludGVnZXIobmdyYW0kd29yZCkKaGxOZ3JhbSA9IGZpbHRlcihuZ3JhbSwgd29yZCA+PSAxODc1KQpobE5ncmFtZiA9IGZpbHRlcihobE5ncmFtLCB3b3JkIDw9IDE5NzUpCgpvcmlnaW5hbGhsID0gbGVmdF9qb2luKGhsTmdyYW1mLCBmaWd1cmVhMiwgYnkgPSAieWVhciIpICU+JQogIG11dGF0ZShmcmVxdWVuY3kgPSBtYXRjaF9jb3VudC54IC8gbWF0Y2hfY291bnQueSkgJT4lCiAgc2VsZWN0KHdvcmQsIHllYXIsIGZyZXF1ZW5jeSkgJT4lCiAgbXV0YXRlKHllYXJHID0geWVhciA+IHdvcmQpICU+JQogIGZpbHRlcih5ZWFyRyA9PSBUUlVFKQpobCA9IG9yaWdpbmFsaGwKYGBgCgoKQWZ0ZXIgZmluZCB0aGUgbWF4IGZyZXF1ZW5jeSBmb3IgZWFjaCB5ZWFyIGFuZCB0aGVuIGZpbHRlciBmcmVxdWVuY3kgYnkgMS8yIHRoZSBtYXguIEFmdGVyd2FyZHMgc3VidHJhY3QgdGhlIDEvMiBmcmVxdWVuY3kgYnkgdGhlIG1heC4KYGBge3J9CmhsTSA9IG9yaWdpbmFsaGwgJT4lIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoZnJlcXVlbmN5ID0gbWF4KGZyZXF1ZW5jeSkpCmhsWSA9IG9yaWdpbmFsaGwgJT4lIGdyb3VwX2J5KHllYXIpIApobFQgPSBsZWZ0X2pvaW4oaGxNLCBobFksIGJ5ID0gImZyZXF1ZW5jeSIsIHN1ZmZpeCA9IGMoIi54IiwgIi55IikpCmhsVCA9IHNlbGVjdChobFQsIHdvcmQueCwgeWVhciwgZnJlcXVlbmN5KQpobFQgPSBobFQgJT4lIGdyb3VwX2J5KHdvcmQueCkgJT4lIGZpbHRlciAoISBkdXBsaWNhdGVkKHdvcmQueCkpICU+JQogIHJlbmFtZSh3b3JkID0gd29yZC54KQpobFQyID0gaGxUICU+JSBzZWxlY3QoZnJlcXVlbmN5KSAlPiUKICBsZWZ0X2pvaW4oaGwsIGhsVCwgYnkgPSAid29yZCIpICU+JQogIGZpbHRlcihmcmVxdWVuY3kueCA+IChmcmVxdWVuY3kueSAvIDIpKSAlPiUKICBzZWxlY3Qod29yZCwgZnJlcXVlbmN5LngsIHllYXIpCgoKaGxGID0gbGVmdF9qb2luKGhsVCwgaGxUMiwgYnkgPSAid29yZCIpICU+JQogIGZpbHRlcih5ZWFyLnkgPiB5ZWFyLngpICU+JQogIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoeWVhci55ID0gbWluKHllYXIueSkpCmhsVCA9IGhsVCAlPiUgc2VsZWN0KHdvcmQsIHllYXIpCmhsRiA9IGxlZnRfam9pbihobEYsIGhsVCwgYnkgPSAid29yZCIpIApobEYgPSBtdXRhdGUoaGxGLCBoYWxmX2xpZmUgPSAoeWVhci55IC0geWVhcikpCmhsRiA9IGhsRiAlPiUgcmVuYW1lKG5ncmFtX3llYXIgPSB3b3JkKQpobEYgPSBobEYgJT4lIHNlbGVjdChuZ3JhbV95ZWFyLCBoYWxmX2xpZmUpCmhsRgpgYGAKCk1ha2UgdGhlIGhhbGYtbGlmZSB2aXp1YWxpemF0aW9uLiAKYGBge3J9CmVuZ2xpc2hobCA9IGdncGxvdChobEYsIGFlcyh4ID0gbmdyYW1feWVhciwgeSA9IGhhbGZfbGlmZSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gOC8xMCkgKwogIGdlb21fc21vb3RoKCkgKwogIGdndGl0bGUoIkVuZ2xpc2giKQplbmdsaXNoaGwKYGBgCkRvZXMgdmVyc2lvbiAyIG9mIHRoZQpOR3JhbSBkYXRhIHByb2R1Y2Ugc2ltaWxhciByZXN1bHRzIHRvIHRob3NlIHByZXNlbnRlZCBpbiBNaWNoZWwgZXQgYWwuCigyMDExKSwgd2hpY2ggYXJlIGJhc2VkIG9uIHZlcnNpb24gMSBkYXRhPyAoSGludDogRG9u4oCZdCBiZSBzdXJwcmlzZWQgaWYgaXQKZG9lc27igJl0LikKICBJdCBkb2VzIG5vdCBhcyBpbiBNaWNoZWwgZXQgYWwuIHRoZWlyIGhhbGYgbGlmZSB2YWx1ZXMgZm9yIGVhcmx5IHllYXJzIG9mIHRoZSByYW5nZSAxODc1LTE5NzUgc3RhcnQgb2ZmIGV4dHJlbWVseSBoaWdoIGF0IDMwIGFuZCB0aGVuIGN1cnZlIGRvd24gbGF0ZXIgaW4gdGhlIHllYXIgcmFuZ2UgdG8gYW4gYXZlcmFnZSBvZiAxNSB5ZWFycyBmb3IgaGFsZi1saWZlLiAKCiNHCmcpIFdlcmUgdGhlcmUgYW55IHllYXJzIHRoYXQgd2VyZSBvdXRsaWVycywgc3VjaCBhcyB5ZWFycyB0aGF0IHdlcmUgZm9yZ290dGVuCnBhcnRpY3VsYXJseSBxdWlja2x5IG9yIHBhcnRpY3VsYXJseSBzbG93bHk/IEJyaWVmbHkgc3BlY3VsYXRlIGFib3V0IHBvc3NpYmxlCnJlYXNvbnMgZm9yIHRoYXQgcGF0dGVybiBhbmQgZXhwbGFpbiBob3cgeW91IGlkZW50aWZpZWQgdGhlIG91dGxpZXJzLgogIEFueSB5ZWFycyB3aXRoIGEgaGFsZi1saWZlID4gMTAgd291bGQgYmUgYW4gb3V0bGllciBhbmQgSSBkZXRlcm1pbmVkIHRoYXQgYnkgdXNpbmcgZ2VvbV9zbW9vdGggd2hpY2ggYXBwbGllcyBhIGNvbmRpdGlvbmFsIG1lYW4gbGluZSBvbnRvIHRoZSBnZ3Bsb3QuIFRoZSBtb3N0IGxpa2VseSBleHBsYW5hdGlvbiBmb3IgdGhlc2Ugb3V0bGllcnMgaXMgaGlzdG9yaWNhbCBldmVudHMgdGhhdCBoYXBwZW5lZCBzdWNoIGFzIHdhcnMgb3IgdHJhZ2VkaWVzLiBGb3IgdGhlIHllYXIgMTkxMiBpdCBoYWQgYSBoYWxmLWxpZmUgb2YgMjYsIGxvb2tpbmcgYXQgdGhlIGV2ZW50cyBvZiB0aGF0IHllYXIsIHRoZXJlIHdhcyB0aGUgdHJhZ2ljIGV2ZW50IG9mIHRoZSBUaXRhbmljIHNpbmtpbmcuIEhvd2V2ZXIgd2hhdCBpcyBzdHJhbmdlIGlzIGlmIG15IGd1ZXNzIHdlcmUgdG8gYmUgdHJ1ZSwgdGhhdCB3b3VsZCBtZWFuIHRoZSB5ZWFyIDE5MTQgd2hpY2ggaXMgdGhlIHN0YXJ0IG9mIFdXMSwgd291bGQgaGF2ZSBhIGhpZ2ggaGFsZi1saWZlLiBMb29raW5nIGF0IGl0LCBpdCBkb2VzIG5vdCBhbmQgbG9va2luZyBhdCB0aGUgZW5kIHllYXIgb2YgV1cxLCAxOTE4LCBpdCBoYXMgYSBoYWxmLWxpZmUgb2YgMSB3aXRoIGEgcGVhayByYXRlIG9mIG1lbnRpb25zIGluIDE5MjEuCiAgCiNICmgpIE5vdyByZXBsaWNhdGUgdGhpcyByZXN1bHQgZm9yIHZlcnNpb24gMiBvZiB0aGUgTkdyYW1zIGRhdGEgaW4gQ2hpbmVzZSwKRnJlbmNoLCBHZXJtYW4sIEhlYnJldywgSXRhbGlhbiwgUnVzc2lhbiBhbmQgU3BhbmlzaC4KCiMjQ2hpbmVzZQpgYGB7cn0KbmdyYW1vcmlnaW5hbGNoaW5lc2UgPSByZWFkLnRhYmxlKCIxZ3JhbWNoaW5lc2UudHh0IikKbmdyYW1jaGluZXNlID0gbmdyYW1vcmlnaW5hbGNoaW5lc2UKbmdyYW1jaGluZXNlID0gbmdyYW1jaGluZXNlICU+JSByZW5hbWUoCiAgd29yZCA9IFYxLAogIHllYXIgPSBWMiwKICBtYXRjaF9jb3VudCA9IFYzLAogIHZvbHVtZV9jb3VudCA9IFY0KQoKdG90YWxjb3VudGNoaW5lc2UgPSByZWFkLnRhYmxlKCJ0b3RhbGNvdW50Y2hpbmVzZS50eHQiLCBzZXAgPSAiXHQiLCBjb2xDbGFzc2VzID0gImNoYXJhY3RlciIpCnRvdGFsY291bnRjaGluZXNlID0gc2VwYXJhdGVfcm93cyh0b3RhbGNvdW50Y2hpbmVzZSwgVjE6VjM2NSwgY29udmVydCA9IFRSVUUpCnJvd25hbWVzKHRvdGFsY291bnRjaGluZXNlKVsxXSA9ICJ5ZWFyIgpyb3duYW1lcyh0b3RhbGNvdW50Y2hpbmVzZSlbMl0gPSAibWF0Y2hfY291bnQiCnJvd25hbWVzKHRvdGFsY291bnRjaGluZXNlKVszXSA9ICJwYWdlX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50Y2hpbmVzZSlbNF0gPSAidm9sdW1lX2NvdW50IgpmaW5hbHRvdGFsY291bnRjaGluZXNlID0gYXMuZGF0YS5mcmFtZSh0KHRvdGFsY291bnRjaGluZXNlKSkKZmluYWx0b3RhbGNvdW50Y2hpbmVzZSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoeWVhciwgbWF0Y2hfY291bnQpLCBhcy5pbnRlZ2VyKQpmaWd1cmVhMmNoaW5lc2UgPSBzZWxlY3QoZmluYWx0b3RhbGNvdW50Y2hpbmVzZSwKICAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICAgbWF0Y2hfY291bnQpCgpuZ3JhbWNoaW5lc2Ukd29yZCA9IGFzLmludGVnZXIobmdyYW1jaGluZXNlJHdvcmQpCmhsTmdyYW1jaGluZXNlID0gZmlsdGVyKG5ncmFtY2hpbmVzZSwgd29yZCA+PSAxODc1KQpobE5ncmFtZmNoaW5lc2UgPSBmaWx0ZXIoaGxOZ3JhbWNoaW5lc2UsIHdvcmQgPD0gMTk3NSkKCm9yaWdpbmFsaGxjaGluZXNlID0gbGVmdF9qb2luKGhsTmdyYW1mY2hpbmVzZSwgZmlndXJlYTJjaGluZXNlLCBieSA9ICJ5ZWFyIikgJT4lCiAgbXV0YXRlKGZyZXF1ZW5jeSA9IG1hdGNoX2NvdW50LnggLyBtYXRjaF9jb3VudC55KSAlPiUKICBzZWxlY3Qod29yZCwgeWVhciwgZnJlcXVlbmN5KSAlPiUKICBtdXRhdGUoeWVhckcgPSB5ZWFyID4gd29yZCkgJT4lCiAgZmlsdGVyKHllYXJHID09IFRSVUUpCmhsY2hpbmVzZSA9IG9yaWdpbmFsaGxjaGluZXNlCgpobE1jaGluZXNlID0gb3JpZ2luYWxobGNoaW5lc2UgJT4lIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoZnJlcXVlbmN5ID0gbWF4KGZyZXF1ZW5jeSkpCmhsWWNoaW5lc2UgPSBvcmlnaW5hbGhsY2hpbmVzZSAlPiUgZ3JvdXBfYnkoeWVhcikgCmhsVGNoaW5lc2UgPSBsZWZ0X2pvaW4oaGxNY2hpbmVzZSwgaGxZY2hpbmVzZSwgYnkgPSAiZnJlcXVlbmN5Iiwgc3VmZml4ID0gYygiLngiLCAiLnkiKSkKaGxUY2hpbmVzZSA9IHNlbGVjdChobFRjaGluZXNlLCB3b3JkLngsIHllYXIsIGZyZXF1ZW5jeSkKaGxUY2hpbmVzZSA9IGhsVGNoaW5lc2UgJT4lIGdyb3VwX2J5KHdvcmQueCkgJT4lIGZpbHRlciAoISBkdXBsaWNhdGVkKHdvcmQueCkpICU+JQogIHJlbmFtZSh3b3JkID0gd29yZC54KQpobFQyY2hpbmVzZSA9IGhsVGNoaW5lc2UgJT4lIHNlbGVjdChmcmVxdWVuY3kpICU+JQogIGxlZnRfam9pbihobGNoaW5lc2UsIGhsVGNoaW5lc2UsIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoZnJlcXVlbmN5LnggPiAoZnJlcXVlbmN5LnkgLyAyKSkgJT4lCiAgc2VsZWN0KHdvcmQsIGZyZXF1ZW5jeS54LCB5ZWFyKQoKCmhsRmNoaW5lc2UgPSBsZWZ0X2pvaW4oaGxUY2hpbmVzZSwgaGxUMmNoaW5lc2UsIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoeWVhci55ID4geWVhci54KSAlPiUKICBncm91cF9ieSh3b3JkKSAlPiUgc3VtbWFyaXNlKHllYXIueSA9IG1pbih5ZWFyLnkpKQpobFRjaGluZXNlID0gaGxUY2hpbmVzZSAlPiUgc2VsZWN0KHdvcmQsIHllYXIpCmhsRmNoaW5lc2UgPSBsZWZ0X2pvaW4oaGxGY2hpbmVzZSwgaGxUY2hpbmVzZSwgYnkgPSAid29yZCIpIApobEZjaGluZXNlID0gbXV0YXRlKGhsRmNoaW5lc2UsIGhhbGZfbGlmZSA9ICh5ZWFyLnkgLSB5ZWFyKSkKaGxGY2hpbmVzZSA9IGhsRmNoaW5lc2UgJT4lIHJlbmFtZShuZ3JhbV95ZWFyID0gd29yZCkKaGxGY2hpbmVzZSA9IGhsRmNoaW5lc2UgJT4lIHNlbGVjdChuZ3JhbV95ZWFyLCBoYWxmX2xpZmUpCgpjaGluZXNlaGwgPSBnZ3Bsb3QoaGxGY2hpbmVzZSwgYWVzKHggPSBuZ3JhbV95ZWFyLCB5ID0gaGFsZl9saWZlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSA4LzEwKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2d0aXRsZSgiQ2hpbmVzZSIpCmNoaW5lc2VobApgYGAKCgoKIyNGcmVuY2gKYGBge3J9Cm5ncmFtb3JpZ2luYWxmcmVuY2ggPSByZWFkLnRhYmxlKCIxZ3JhbWZyZW5jaC50eHQiKQpuZ3JhbWZyZW5jaCA9IG5ncmFtb3JpZ2luYWxmcmVuY2gKbmdyYW1mcmVuY2ggPSBuZ3JhbWZyZW5jaCAlPiUgcmVuYW1lKAogIHdvcmQgPSBWMSwKICB5ZWFyID0gVjIsCiAgbWF0Y2hfY291bnQgPSBWMywKICB2b2x1bWVfY291bnQgPSBWNCkKCnRvdGFsY291bnRmcmVuY2ggPSByZWFkLnRhYmxlKCJ0b3RhbGNvdW50ZnJlbmNoLnR4dCIsIHNlcCA9ICJcdCIsIGNvbENsYXNzZXMgPSAiY2hhcmFjdGVyIikKdG90YWxjb3VudGZyZW5jaCA9IHNlcGFyYXRlX3Jvd3ModG90YWxjb3VudGZyZW5jaCwgVjE6VjQyMSwgY29udmVydCA9IFRSVUUpCnJvd25hbWVzKHRvdGFsY291bnRmcmVuY2gpWzFdID0gInllYXIiCnJvd25hbWVzKHRvdGFsY291bnRmcmVuY2gpWzJdID0gIm1hdGNoX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50ZnJlbmNoKVszXSA9ICJwYWdlX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50ZnJlbmNoKVs0XSA9ICJ2b2x1bWVfY291bnQiCmZpbmFsdG90YWxjb3VudGZyZW5jaCA9IGFzLmRhdGEuZnJhbWUodCh0b3RhbGNvdW50ZnJlbmNoKSkKZmluYWx0b3RhbGNvdW50ZnJlbmNoICU+JSAKICBtdXRhdGVfYXQodmFycyh5ZWFyLCBtYXRjaF9jb3VudCksIGFzLmludGVnZXIpCmZpZ3VyZWEyZnJlbmNoID0gc2VsZWN0KGZpbmFsdG90YWxjb3VudGZyZW5jaCwKICAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICAgbWF0Y2hfY291bnQpCgpuZ3JhbWZyZW5jaCR3b3JkID0gYXMuaW50ZWdlcihuZ3JhbWZyZW5jaCR3b3JkKQpobE5ncmFtZnJlbmNoID0gZmlsdGVyKG5ncmFtZnJlbmNoLCB3b3JkID49IDE4NzUpCmhsTmdyYW1mZnJlbmNoID0gZmlsdGVyKGhsTmdyYW1mcmVuY2gsIHdvcmQgPD0gMTk3NSkKCm9yaWdpbmFsaGxmcmVuY2ggPSBsZWZ0X2pvaW4oaGxOZ3JhbWZmcmVuY2gsIGZpZ3VyZWEyZnJlbmNoLCBieSA9ICJ5ZWFyIikgJT4lCiAgbXV0YXRlKGZyZXF1ZW5jeSA9IG1hdGNoX2NvdW50LnggLyBtYXRjaF9jb3VudC55KSAlPiUKICBzZWxlY3Qod29yZCwgeWVhciwgZnJlcXVlbmN5KSAlPiUKICBtdXRhdGUoeWVhckcgPSB5ZWFyID4gd29yZCkgJT4lCiAgZmlsdGVyKHllYXJHID09IFRSVUUpCmhsZnJlbmNoID0gb3JpZ2luYWxobGZyZW5jaAoKaGxNZnJlbmNoID0gb3JpZ2luYWxobGZyZW5jaCAlPiUgZ3JvdXBfYnkod29yZCkgJT4lIHN1bW1hcmlzZShmcmVxdWVuY3kgPSBtYXgoZnJlcXVlbmN5KSkKaGxZZnJlbmNoID0gb3JpZ2luYWxobGZyZW5jaCAlPiUgZ3JvdXBfYnkoeWVhcikgCmhsVGZyZW5jaCA9IGxlZnRfam9pbihobE1mcmVuY2gsIGhsWWZyZW5jaCwgYnkgPSAiZnJlcXVlbmN5Iiwgc3VmZml4ID0gYygiLngiLCAiLnkiKSkKaGxUZnJlbmNoID0gc2VsZWN0KGhsVGZyZW5jaCwgd29yZC54LCB5ZWFyLCBmcmVxdWVuY3kpCmhsVGZyZW5jaCA9IGhsVGZyZW5jaCAlPiUgZ3JvdXBfYnkod29yZC54KSAlPiUgZmlsdGVyICghIGR1cGxpY2F0ZWQod29yZC54KSkgJT4lCiAgcmVuYW1lKHdvcmQgPSB3b3JkLngpCmhsVDJmcmVuY2ggPSBobFRmcmVuY2ggJT4lIHNlbGVjdChmcmVxdWVuY3kpICU+JQogIGxlZnRfam9pbihobGZyZW5jaCwgaGxUZnJlbmNoLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKGZyZXF1ZW5jeS54ID4gKGZyZXF1ZW5jeS55IC8gMikpICU+JQogIHNlbGVjdCh3b3JkLCBmcmVxdWVuY3kueCwgeWVhcikKCgpobEZmcmVuY2ggPSBsZWZ0X2pvaW4oaGxUZnJlbmNoLCBobFQyZnJlbmNoLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKHllYXIueSA+IHllYXIueCkgJT4lCiAgZ3JvdXBfYnkod29yZCkgJT4lIHN1bW1hcmlzZSh5ZWFyLnkgPSBtaW4oeWVhci55KSkKaGxUZnJlbmNoID0gaGxUZnJlbmNoICU+JSBzZWxlY3Qod29yZCwgeWVhcikKaGxGZnJlbmNoID0gbGVmdF9qb2luKGhsRmZyZW5jaCwgaGxUZnJlbmNoLCBieSA9ICJ3b3JkIikgCmhsRmZyZW5jaCA9IG11dGF0ZShobEZmcmVuY2gsIGhhbGZfbGlmZSA9ICh5ZWFyLnkgLSB5ZWFyKSkKaGxGZnJlbmNoID0gaGxGZnJlbmNoICU+JSByZW5hbWUobmdyYW1feWVhciA9IHdvcmQpCmhsRmZyZW5jaCA9IGhsRmZyZW5jaCAlPiUgc2VsZWN0KG5ncmFtX3llYXIsIGhhbGZfbGlmZSkKCmZyZW5jaGhsID0gZ2dwbG90KGhsRmZyZW5jaCwgYWVzKHggPSBuZ3JhbV95ZWFyLCB5ID0gaGFsZl9saWZlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSA4LzEwKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2d0aXRsZSgiRnJlbmNoIikKZnJlbmNoaGwKYGBgCgoKIyNHZXJtYW4KYGBge3J9Cm5ncmFtb3JpZ2luYWxnZXJtYW4gPSByZWFkLnRhYmxlKCIxZ3JhbWdlcm1hbi50eHQiKQpuZ3JhbWdlcm1hbiA9IG5ncmFtb3JpZ2luYWxnZXJtYW4KbmdyYW1nZXJtYW4gPSBuZ3JhbWdlcm1hbiAlPiUgcmVuYW1lKAogIHdvcmQgPSBWMSwKICB5ZWFyID0gVjIsCiAgbWF0Y2hfY291bnQgPSBWMywKICB2b2x1bWVfY291bnQgPSBWNCkKCnRvdGFsY291bnRnZXJtYW4gPSByZWFkLnRhYmxlKCJ0b3RhbGNvdW50Z2VybWFuLnR4dCIsIHNlcCA9ICJcdCIsIGNvbENsYXNzZXMgPSAiY2hhcmFjdGVyIikKdG90YWxjb3VudGdlcm1hbiA9IHNlcGFyYXRlX3Jvd3ModG90YWxjb3VudGdlcm1hbiwgVjE6VjMxNywgY29udmVydCA9IFRSVUUpCnJvd25hbWVzKHRvdGFsY291bnRnZXJtYW4pWzFdID0gInllYXIiCnJvd25hbWVzKHRvdGFsY291bnRnZXJtYW4pWzJdID0gIm1hdGNoX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50Z2VybWFuKVszXSA9ICJwYWdlX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50Z2VybWFuKVs0XSA9ICJ2b2x1bWVfY291bnQiCmZpbmFsdG90YWxjb3VudGdlcm1hbiA9IGFzLmRhdGEuZnJhbWUodCh0b3RhbGNvdW50Z2VybWFuKSkKZmluYWx0b3RhbGNvdW50Z2VybWFuICU+JSAKICBtdXRhdGVfYXQodmFycyh5ZWFyLCBtYXRjaF9jb3VudCksIGFzLmludGVnZXIpCmZpZ3VyZWEyZ2VybWFuID0gc2VsZWN0KGZpbmFsdG90YWxjb3VudGdlcm1hbiwKICAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICAgbWF0Y2hfY291bnQpCgpuZ3JhbWdlcm1hbiR3b3JkID0gYXMuaW50ZWdlcihuZ3JhbWdlcm1hbiR3b3JkKQpobE5ncmFtZ2VybWFuID0gZmlsdGVyKG5ncmFtZ2VybWFuLCB3b3JkID49IDE4NzUpCmhsTmdyYW1mZ2VybWFuID0gZmlsdGVyKGhsTmdyYW1nZXJtYW4sIHdvcmQgPD0gMTk3NSkKCm9yaWdpbmFsaGxnZXJtYW4gPSBsZWZ0X2pvaW4oaGxOZ3JhbWZnZXJtYW4sIGZpZ3VyZWEyZ2VybWFuLCBieSA9ICJ5ZWFyIikgJT4lCiAgbXV0YXRlKGZyZXF1ZW5jeSA9IG1hdGNoX2NvdW50LnggLyBtYXRjaF9jb3VudC55KSAlPiUKICBzZWxlY3Qod29yZCwgeWVhciwgZnJlcXVlbmN5KSAlPiUKICBtdXRhdGUoeWVhckcgPSB5ZWFyID4gd29yZCkgJT4lCiAgZmlsdGVyKHllYXJHID09IFRSVUUpCmhsZ2VybWFuID0gb3JpZ2luYWxobGdlcm1hbgoKaGxNZ2VybWFuID0gb3JpZ2luYWxobGdlcm1hbiAlPiUgZ3JvdXBfYnkod29yZCkgJT4lIHN1bW1hcmlzZShmcmVxdWVuY3kgPSBtYXgoZnJlcXVlbmN5KSkKaGxZZ2VybWFuID0gb3JpZ2luYWxobGdlcm1hbiAlPiUgZ3JvdXBfYnkoeWVhcikgCmhsVGdlcm1hbiA9IGxlZnRfam9pbihobE1nZXJtYW4sIGhsWWdlcm1hbiwgYnkgPSAiZnJlcXVlbmN5Iiwgc3VmZml4ID0gYygiLngiLCAiLnkiKSkKaGxUZ2VybWFuID0gc2VsZWN0KGhsVGdlcm1hbiwgd29yZC54LCB5ZWFyLCBmcmVxdWVuY3kpCmhsVGdlcm1hbiA9IGhsVGdlcm1hbiAlPiUgZ3JvdXBfYnkod29yZC54KSAlPiUgZmlsdGVyICghIGR1cGxpY2F0ZWQod29yZC54KSkgJT4lCiAgcmVuYW1lKHdvcmQgPSB3b3JkLngpCmhsVDJnZXJtYW4gPSBobFRnZXJtYW4gJT4lIHNlbGVjdChmcmVxdWVuY3kpICU+JQogIGxlZnRfam9pbihobGdlcm1hbiwgaGxUZ2VybWFuLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKGZyZXF1ZW5jeS54ID4gKGZyZXF1ZW5jeS55IC8gMikpICU+JQogIHNlbGVjdCh3b3JkLCBmcmVxdWVuY3kueCwgeWVhcikKCgpobEZnZXJtYW4gPSBsZWZ0X2pvaW4oaGxUZ2VybWFuLCBobFQyZ2VybWFuLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKHllYXIueSA+IHllYXIueCkgJT4lCiAgZ3JvdXBfYnkod29yZCkgJT4lIHN1bW1hcmlzZSh5ZWFyLnkgPSBtaW4oeWVhci55KSkKaGxUZ2VybWFuID0gaGxUZ2VybWFuICU+JSBzZWxlY3Qod29yZCwgeWVhcikKaGxGZ2VybWFuID0gbGVmdF9qb2luKGhsRmdlcm1hbiwgaGxUZ2VybWFuLCBieSA9ICJ3b3JkIikgCmhsRmdlcm1hbiA9IG11dGF0ZShobEZnZXJtYW4sIGhhbGZfbGlmZSA9ICh5ZWFyLnkgLSB5ZWFyKSkKaGxGZ2VybWFuID0gaGxGZ2VybWFuICU+JSByZW5hbWUobmdyYW1feWVhciA9IHdvcmQpCmhsRmdlcm1hbiA9IGhsRmdlcm1hbiAlPiUgc2VsZWN0KG5ncmFtX3llYXIsIGhhbGZfbGlmZSkKCmdlcm1hbmhsID0gZ2dwbG90KGhsRmdlcm1hbiwgYWVzKHggPSBuZ3JhbV95ZWFyLCB5ID0gaGFsZl9saWZlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSA4LzEwKSArCiAgZ2VvbV9zbW9vdGgoKSArIAogIGdndGl0bGUoIkdlcm1hbiIpCmdlcm1hbmhsCmBgYAoKCiMjSGVicmV3CmBgYHtyfQpuZ3JhbW9yaWdpbmFsaGVicmV3ID0gcmVhZC50YWJsZSgiMWdyYW1oZWJyZXcudHh0IikKbmdyYW1oZWJyZXcgPSBuZ3JhbW9yaWdpbmFsaGVicmV3Cm5ncmFtaGVicmV3ID0gbmdyYW1oZWJyZXcgJT4lIHJlbmFtZSgKICB3b3JkID0gVjEsCiAgeWVhciA9IFYyLAogIG1hdGNoX2NvdW50ID0gVjMsCiAgdm9sdW1lX2NvdW50ID0gVjQpCgp0b3RhbGNvdW50aGVicmV3ID0gcmVhZC50YWJsZSgidG90YWxjb3VudGhlYnJldy50eHQiLCBzZXAgPSAiXHQiLCBjb2xDbGFzc2VzID0gImNoYXJhY3RlciIpCnRvdGFsY291bnRoZWJyZXcgPSBzZXBhcmF0ZV9yb3dzKHRvdGFsY291bnRoZWJyZXcsIFYxOlYzMzksIGNvbnZlcnQgPSBUUlVFKQpyb3duYW1lcyh0b3RhbGNvdW50aGVicmV3KVsxXSA9ICJ5ZWFyIgpyb3duYW1lcyh0b3RhbGNvdW50aGVicmV3KVsyXSA9ICJtYXRjaF9jb3VudCIKcm93bmFtZXModG90YWxjb3VudGhlYnJldylbM10gPSAicGFnZV9jb3VudCIKcm93bmFtZXModG90YWxjb3VudGhlYnJldylbNF0gPSAidm9sdW1lX2NvdW50IgpmaW5hbHRvdGFsY291bnRoZWJyZXcgPSBhcy5kYXRhLmZyYW1lKHQodG90YWxjb3VudGhlYnJldykpCmZpbmFsdG90YWxjb3VudGhlYnJldyAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoeWVhciwgbWF0Y2hfY291bnQpLCBhcy5pbnRlZ2VyKQpmaWd1cmVhMmhlYnJldyA9IHNlbGVjdChmaW5hbHRvdGFsY291bnRoZWJyZXcsCiAgICAgICAgICAgICAgICAgIHllYXIsCiAgICAgICAgICAgICAgICAgIG1hdGNoX2NvdW50KQoKbmdyYW1oZWJyZXckd29yZCA9IGFzLmludGVnZXIobmdyYW1oZWJyZXckd29yZCkKaGxOZ3JhbWhlYnJldyA9IGZpbHRlcihuZ3JhbWhlYnJldywgd29yZCA+PSAxODc1KQpobE5ncmFtZmhlYnJldyA9IGZpbHRlcihobE5ncmFtaGVicmV3LCB3b3JkIDw9IDE5NzUpCgpvcmlnaW5hbGhsaGVicmV3ID0gbGVmdF9qb2luKGhsTmdyYW1maGVicmV3LCBmaWd1cmVhMmhlYnJldywgYnkgPSAieWVhciIpICU+JQogIG11dGF0ZShmcmVxdWVuY3kgPSBtYXRjaF9jb3VudC54IC8gbWF0Y2hfY291bnQueSkgJT4lCiAgc2VsZWN0KHdvcmQsIHllYXIsIGZyZXF1ZW5jeSkgJT4lCiAgbXV0YXRlKHllYXJHID0geWVhciA+IHdvcmQpICU+JQogIGZpbHRlcih5ZWFyRyA9PSBUUlVFKQpobGhlYnJldyA9IG9yaWdpbmFsaGxoZWJyZXcKCmhsTWhlYnJldyA9IG9yaWdpbmFsaGxoZWJyZXcgJT4lIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoZnJlcXVlbmN5ID0gbWF4KGZyZXF1ZW5jeSkpCmhsWWhlYnJldyA9IG9yaWdpbmFsaGxoZWJyZXcgJT4lIGdyb3VwX2J5KHllYXIpIApobFRoZWJyZXcgPSBsZWZ0X2pvaW4oaGxNaGVicmV3LCBobFloZWJyZXcsIGJ5ID0gImZyZXF1ZW5jeSIsIHN1ZmZpeCA9IGMoIi54IiwgIi55IikpCmhsVGhlYnJldyA9IHNlbGVjdChobFRoZWJyZXcsIHdvcmQueCwgeWVhciwgZnJlcXVlbmN5KQpobFRoZWJyZXcgPSBobFRoZWJyZXcgJT4lIGdyb3VwX2J5KHdvcmQueCkgJT4lIGZpbHRlciAoISBkdXBsaWNhdGVkKHdvcmQueCkpICU+JQogIHJlbmFtZSh3b3JkID0gd29yZC54KQpobFQyaGVicmV3ID0gaGxUaGVicmV3ICU+JSBzZWxlY3QoZnJlcXVlbmN5KSAlPiUKICBsZWZ0X2pvaW4oaGxoZWJyZXcsIGhsVGhlYnJldywgYnkgPSAid29yZCIpICU+JQogIGZpbHRlcihmcmVxdWVuY3kueCA+IChmcmVxdWVuY3kueSAvIDIpKSAlPiUKICBzZWxlY3Qod29yZCwgZnJlcXVlbmN5LngsIHllYXIpCgoKaGxGaGVicmV3ID0gbGVmdF9qb2luKGhsVGhlYnJldywgaGxUMmhlYnJldywgYnkgPSAid29yZCIpICU+JQogIGZpbHRlcih5ZWFyLnkgPiB5ZWFyLngpICU+JQogIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoeWVhci55ID0gbWluKHllYXIueSkpCmhsVGhlYnJldyA9IGhsVGhlYnJldyAlPiUgc2VsZWN0KHdvcmQsIHllYXIpCmhsRmhlYnJldyA9IGxlZnRfam9pbihobEZoZWJyZXcsIGhsVGhlYnJldywgYnkgPSAid29yZCIpIApobEZoZWJyZXcgPSBtdXRhdGUoaGxGaGVicmV3LCBoYWxmX2xpZmUgPSAoeWVhci55IC0geWVhcikpCmhsRmhlYnJldyA9IGhsRmhlYnJldyAlPiUgcmVuYW1lKG5ncmFtX3llYXIgPSB3b3JkKQpobEZoZWJyZXcgPSBobEZoZWJyZXcgJT4lIHNlbGVjdChuZ3JhbV95ZWFyLCBoYWxmX2xpZmUpCgpoZWJyZXdobCA9IGdncGxvdChobEZoZWJyZXcsIGFlcyh4ID0gbmdyYW1feWVhciwgeSA9IGhhbGZfbGlmZSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gOC8xMCkgKwogIGdlb21fc21vb3RoKCkgKwogIGdndGl0bGUoIkhlYnJldyIpCmhlYnJld2hsCmBgYAoKCiMjSXRhbGlhbgpgYGB7cn0KbmdyYW1vcmlnaW5hbGl0YWxpYW4gPSByZWFkLnRhYmxlKCIxZ3JhbWl0YWxpYW4udHh0IikKbmdyYW1pdGFsaWFuID0gbmdyYW1vcmlnaW5hbGl0YWxpYW4KbmdyYW1pdGFsaWFuID0gbmdyYW1pdGFsaWFuICU+JSByZW5hbWUoCiAgd29yZCA9IFYxLAogIHllYXIgPSBWMiwKICBtYXRjaF9jb3VudCA9IFYzLAogIHZvbHVtZV9jb3VudCA9IFY0KQoKdG90YWxjb3VudGl0YWxpYW4gPSByZWFkLnRhYmxlKCJ0b3RhbGNvdW50aXRhbGlhbi50eHQiLCBzZXAgPSAiXHQiLCBjb2xDbGFzc2VzID0gImNoYXJhY3RlciIpCnRvdGFsY291bnRpdGFsaWFuID0gc2VwYXJhdGVfcm93cyh0b3RhbGNvdW50aXRhbGlhbiwgVjE6VjM1NiwgY29udmVydCA9IFRSVUUpCnJvd25hbWVzKHRvdGFsY291bnRpdGFsaWFuKVsxXSA9ICJ5ZWFyIgpyb3duYW1lcyh0b3RhbGNvdW50aXRhbGlhbilbMl0gPSAibWF0Y2hfY291bnQiCnJvd25hbWVzKHRvdGFsY291bnRpdGFsaWFuKVszXSA9ICJwYWdlX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50aXRhbGlhbilbNF0gPSAidm9sdW1lX2NvdW50IgpmaW5hbHRvdGFsY291bnRpdGFsaWFuID0gYXMuZGF0YS5mcmFtZSh0KHRvdGFsY291bnRpdGFsaWFuKSkKZmluYWx0b3RhbGNvdW50aXRhbGlhbiAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoeWVhciwgbWF0Y2hfY291bnQpLCBhcy5pbnRlZ2VyKQpmaWd1cmVhMml0YWxpYW4gPSBzZWxlY3QoZmluYWx0b3RhbGNvdW50aXRhbGlhbiwKICAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICAgbWF0Y2hfY291bnQpCgpuZ3JhbWl0YWxpYW4kd29yZCA9IGFzLmludGVnZXIobmdyYW1pdGFsaWFuJHdvcmQpCmhsTmdyYW1pdGFsaWFuID0gZmlsdGVyKG5ncmFtaXRhbGlhbiwgd29yZCA+PSAxODc1KQpobE5ncmFtZml0YWxpYW4gPSBmaWx0ZXIoaGxOZ3JhbWl0YWxpYW4sIHdvcmQgPD0gMTk3NSkKCm9yaWdpbmFsaGxpdGFsaWFuID0gbGVmdF9qb2luKGhsTmdyYW1maXRhbGlhbiwgZmlndXJlYTJpdGFsaWFuLCBieSA9ICJ5ZWFyIikgJT4lCiAgbXV0YXRlKGZyZXF1ZW5jeSA9IG1hdGNoX2NvdW50LnggLyBtYXRjaF9jb3VudC55KSAlPiUKICBzZWxlY3Qod29yZCwgeWVhciwgZnJlcXVlbmN5KSAlPiUKICBtdXRhdGUoeWVhckcgPSB5ZWFyID4gd29yZCkgJT4lCiAgZmlsdGVyKHllYXJHID09IFRSVUUpCmhsaXRhbGlhbiA9IG9yaWdpbmFsaGxpdGFsaWFuCgpobE1pdGFsaWFuID0gb3JpZ2luYWxobGl0YWxpYW4gJT4lIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoZnJlcXVlbmN5ID0gbWF4KGZyZXF1ZW5jeSkpCmhsWWl0YWxpYW4gPSBvcmlnaW5hbGhsaXRhbGlhbiAlPiUgZ3JvdXBfYnkoeWVhcikgCmhsVGl0YWxpYW4gPSBsZWZ0X2pvaW4oaGxNaXRhbGlhbiwgaGxZaXRhbGlhbiwgYnkgPSAiZnJlcXVlbmN5Iiwgc3VmZml4ID0gYygiLngiLCAiLnkiKSkKaGxUaXRhbGlhbiA9IHNlbGVjdChobFRpdGFsaWFuLCB3b3JkLngsIHllYXIsIGZyZXF1ZW5jeSkKaGxUaXRhbGlhbiA9IGhsVGl0YWxpYW4gJT4lIGdyb3VwX2J5KHdvcmQueCkgJT4lIGZpbHRlciAoISBkdXBsaWNhdGVkKHdvcmQueCkpICU+JQogIHJlbmFtZSh3b3JkID0gd29yZC54KQpobFQyaXRhbGlhbiA9IGhsVGl0YWxpYW4gJT4lIHNlbGVjdChmcmVxdWVuY3kpICU+JQogIGxlZnRfam9pbihobGl0YWxpYW4sIGhsVGl0YWxpYW4sIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoZnJlcXVlbmN5LnggPiAoZnJlcXVlbmN5LnkgLyAyKSkgJT4lCiAgc2VsZWN0KHdvcmQsIGZyZXF1ZW5jeS54LCB5ZWFyKQoKCmhsRml0YWxpYW4gPSBsZWZ0X2pvaW4oaGxUaXRhbGlhbiwgaGxUMml0YWxpYW4sIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoeWVhci55ID4geWVhci54KSAlPiUKICBncm91cF9ieSh3b3JkKSAlPiUgc3VtbWFyaXNlKHllYXIueSA9IG1pbih5ZWFyLnkpKQpobFRpdGFsaWFuID0gaGxUaXRhbGlhbiAlPiUgc2VsZWN0KHdvcmQsIHllYXIpCmhsRml0YWxpYW4gPSBsZWZ0X2pvaW4oaGxGaXRhbGlhbiwgaGxUaXRhbGlhbiwgYnkgPSAid29yZCIpIApobEZpdGFsaWFuID0gbXV0YXRlKGhsRml0YWxpYW4sIGhhbGZfbGlmZSA9ICh5ZWFyLnkgLSB5ZWFyKSkKaGxGaXRhbGlhbiA9IGhsRml0YWxpYW4gJT4lIHJlbmFtZShuZ3JhbV95ZWFyID0gd29yZCkKaGxGaXRhbGlhbiA9IGhsRml0YWxpYW4gJT4lIHNlbGVjdChuZ3JhbV95ZWFyLCBoYWxmX2xpZmUpCgppdGFsaWFuaGwgPSBnZ3Bsb3QoaGxGaXRhbGlhbiwgYWVzKHggPSBuZ3JhbV95ZWFyLCB5ID0gaGFsZl9saWZlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSA4LzEwKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2d0aXRsZSgiSXRhbGlhbiIpCml0YWxpYW5obApgYGAKCiMjUnVzc2lhbgpgYGB7cn0KbmdyYW1vcmlnaW5hbHJ1c3NpYW4gPSByZWFkLnRhYmxlKCIxZ3JhbXJ1c3NpYW4udHh0IikKbmdyYW1ydXNzaWFuID0gbmdyYW1vcmlnaW5hbHJ1c3NpYW4KbmdyYW1ydXNzaWFuID0gbmdyYW1ydXNzaWFuICU+JSByZW5hbWUoCiAgd29yZCA9IFYxLAogIHllYXIgPSBWMiwKICBtYXRjaF9jb3VudCA9IFYzLAogIHZvbHVtZV9jb3VudCA9IFY0KQoKdG90YWxjb3VudHJ1c3NpYW4gPSByZWFkLnRhYmxlKCJ0b3RhbGNvdW50cnVzc2lhbi50eHQiLCBzZXAgPSAiXHQiLCBjb2xDbGFzc2VzID0gImNoYXJhY3RlciIpCnRvdGFsY291bnRydXNzaWFuID0gc2VwYXJhdGVfcm93cyh0b3RhbGNvdW50cnVzc2lhbiwgVjE6VjI4NywgY29udmVydCA9IFRSVUUpCnJvd25hbWVzKHRvdGFsY291bnRydXNzaWFuKVsxXSA9ICJ5ZWFyIgpyb3duYW1lcyh0b3RhbGNvdW50cnVzc2lhbilbMl0gPSAibWF0Y2hfY291bnQiCnJvd25hbWVzKHRvdGFsY291bnRydXNzaWFuKVszXSA9ICJwYWdlX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50cnVzc2lhbilbNF0gPSAidm9sdW1lX2NvdW50IgpmaW5hbHRvdGFsY291bnRydXNzaWFuID0gYXMuZGF0YS5mcmFtZSh0KHRvdGFsY291bnRydXNzaWFuKSkKZmluYWx0b3RhbGNvdW50cnVzc2lhbiAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoeWVhciwgbWF0Y2hfY291bnQpLCBhcy5pbnRlZ2VyKQpmaWd1cmVhMnJ1c3NpYW4gPSBzZWxlY3QoZmluYWx0b3RhbGNvdW50cnVzc2lhbiwKICAgICAgICAgICAgICAgICAgeWVhciwKICAgICAgICAgICAgICAgICAgbWF0Y2hfY291bnQpCgpuZ3JhbXJ1c3NpYW4kd29yZCA9IGFzLmludGVnZXIobmdyYW1ydXNzaWFuJHdvcmQpCmhsTmdyYW1ydXNzaWFuID0gZmlsdGVyKG5ncmFtcnVzc2lhbiwgd29yZCA+PSAxODc1KQpobE5ncmFtZnJ1c3NpYW4gPSBmaWx0ZXIoaGxOZ3JhbXJ1c3NpYW4sIHdvcmQgPD0gMTk3NSkKCm9yaWdpbmFsaGxydXNzaWFuID0gbGVmdF9qb2luKGhsTmdyYW1mcnVzc2lhbiwgZmlndXJlYTJydXNzaWFuLCBieSA9ICJ5ZWFyIikgJT4lCiAgbXV0YXRlKGZyZXF1ZW5jeSA9IG1hdGNoX2NvdW50LnggLyBtYXRjaF9jb3VudC55KSAlPiUKICBzZWxlY3Qod29yZCwgeWVhciwgZnJlcXVlbmN5KSAlPiUKICBtdXRhdGUoeWVhckcgPSB5ZWFyID4gd29yZCkgJT4lCiAgZmlsdGVyKHllYXJHID09IFRSVUUpCmhscnVzc2lhbiA9IG9yaWdpbmFsaGxydXNzaWFuCgpobE1ydXNzaWFuID0gb3JpZ2luYWxobHJ1c3NpYW4gJT4lIGdyb3VwX2J5KHdvcmQpICU+JSBzdW1tYXJpc2UoZnJlcXVlbmN5ID0gbWF4KGZyZXF1ZW5jeSkpCmhsWXJ1c3NpYW4gPSBvcmlnaW5hbGhscnVzc2lhbiAlPiUgZ3JvdXBfYnkoeWVhcikgCmhsVHJ1c3NpYW4gPSBsZWZ0X2pvaW4oaGxNcnVzc2lhbiwgaGxZcnVzc2lhbiwgYnkgPSAiZnJlcXVlbmN5Iiwgc3VmZml4ID0gYygiLngiLCAiLnkiKSkKaGxUcnVzc2lhbiA9IHNlbGVjdChobFRydXNzaWFuLCB3b3JkLngsIHllYXIsIGZyZXF1ZW5jeSkKaGxUcnVzc2lhbiA9IGhsVHJ1c3NpYW4gJT4lIGdyb3VwX2J5KHdvcmQueCkgJT4lIGZpbHRlciAoISBkdXBsaWNhdGVkKHdvcmQueCkpICU+JQogIHJlbmFtZSh3b3JkID0gd29yZC54KQpobFQycnVzc2lhbiA9IGhsVHJ1c3NpYW4gJT4lIHNlbGVjdChmcmVxdWVuY3kpICU+JQogIGxlZnRfam9pbihobHJ1c3NpYW4sIGhsVHJ1c3NpYW4sIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoZnJlcXVlbmN5LnggPiAoZnJlcXVlbmN5LnkgLyAyKSkgJT4lCiAgc2VsZWN0KHdvcmQsIGZyZXF1ZW5jeS54LCB5ZWFyKQoKCmhsRnJ1c3NpYW4gPSBsZWZ0X2pvaW4oaGxUcnVzc2lhbiwgaGxUMnJ1c3NpYW4sIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoeWVhci55ID4geWVhci54KSAlPiUKICBncm91cF9ieSh3b3JkKSAlPiUgc3VtbWFyaXNlKHllYXIueSA9IG1pbih5ZWFyLnkpKQpobFRydXNzaWFuID0gaGxUcnVzc2lhbiAlPiUgc2VsZWN0KHdvcmQsIHllYXIpCmhsRnJ1c3NpYW4gPSBsZWZ0X2pvaW4oaGxGcnVzc2lhbiwgaGxUcnVzc2lhbiwgYnkgPSAid29yZCIpIApobEZydXNzaWFuID0gbXV0YXRlKGhsRnJ1c3NpYW4sIGhhbGZfbGlmZSA9ICh5ZWFyLnkgLSB5ZWFyKSkKaGxGcnVzc2lhbiA9IGhsRnJ1c3NpYW4gJT4lIHJlbmFtZShuZ3JhbV95ZWFyID0gd29yZCkKaGxGcnVzc2lhbiA9IGhsRnJ1c3NpYW4gJT4lIHNlbGVjdChuZ3JhbV95ZWFyLCBoYWxmX2xpZmUpCgpydXNzaWFuaGwgPSBnZ3Bsb3QoaGxGcnVzc2lhbiwgYWVzKHggPSBuZ3JhbV95ZWFyLCB5ID0gaGFsZl9saWZlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSA4LzEwKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2d0aXRsZSgiUnVzc2lhbiIpCnJ1c3NpYW5obApgYGAKCgojI1NwYW5pc2gKYGBge3J9Cm5ncmFtb3JpZ2luYWxzcGFuaXNoID0gcmVhZC50YWJsZSgiMWdyYW1zcGFuaXNoLnR4dCIpCm5ncmFtc3BhbmlzaCA9IG5ncmFtb3JpZ2luYWxzcGFuaXNoCm5ncmFtc3BhbmlzaCA9IG5ncmFtc3BhbmlzaCAlPiUgcmVuYW1lKAogIHdvcmQgPSBWMSwKICB5ZWFyID0gVjIsCiAgbWF0Y2hfY291bnQgPSBWMywKICB2b2x1bWVfY291bnQgPSBWNCkKCnRvdGFsY291bnRzcGFuaXNoID0gcmVhZC50YWJsZSgidG90YWxjb3VudHNwYW5pc2gudHh0Iiwgc2VwID0gIlx0IiwgY29sQ2xhc3NlcyA9ICJjaGFyYWN0ZXIiKQp0b3RhbGNvdW50c3BhbmlzaCA9IHNlcGFyYXRlX3Jvd3ModG90YWxjb3VudHNwYW5pc2gsIFYxOlY0MDUsIGNvbnZlcnQgPSBUUlVFKQpyb3duYW1lcyh0b3RhbGNvdW50c3BhbmlzaClbMV0gPSAieWVhciIKcm93bmFtZXModG90YWxjb3VudHNwYW5pc2gpWzJdID0gIm1hdGNoX2NvdW50Igpyb3duYW1lcyh0b3RhbGNvdW50c3BhbmlzaClbM10gPSAicGFnZV9jb3VudCIKcm93bmFtZXModG90YWxjb3VudHNwYW5pc2gpWzRdID0gInZvbHVtZV9jb3VudCIKZmluYWx0b3RhbGNvdW50c3BhbmlzaCA9IGFzLmRhdGEuZnJhbWUodCh0b3RhbGNvdW50c3BhbmlzaCkpCmZpbmFsdG90YWxjb3VudHNwYW5pc2ggJT4lIAogIG11dGF0ZV9hdCh2YXJzKHllYXIsIG1hdGNoX2NvdW50KSwgYXMuaW50ZWdlcikKZmlndXJlYTJzcGFuaXNoID0gc2VsZWN0KGZpbmFsdG90YWxjb3VudHNwYW5pc2gsCiAgICAgICAgICAgICAgICAgIHllYXIsCiAgICAgICAgICAgICAgICAgIG1hdGNoX2NvdW50KQoKbmdyYW1zcGFuaXNoJHdvcmQgPSBhcy5pbnRlZ2VyKG5ncmFtc3BhbmlzaCR3b3JkKQpobE5ncmFtc3BhbmlzaCA9IGZpbHRlcihuZ3JhbXNwYW5pc2gsIHdvcmQgPj0gMTg3NSkKaGxOZ3JhbWZzcGFuaXNoID0gZmlsdGVyKGhsTmdyYW1zcGFuaXNoLCB3b3JkIDw9IDE5NzUpCgpvcmlnaW5hbGhsc3BhbmlzaCA9IGxlZnRfam9pbihobE5ncmFtZnNwYW5pc2gsIGZpZ3VyZWEyc3BhbmlzaCwgYnkgPSAieWVhciIpICU+JQogIG11dGF0ZShmcmVxdWVuY3kgPSBtYXRjaF9jb3VudC54IC8gbWF0Y2hfY291bnQueSkgJT4lCiAgc2VsZWN0KHdvcmQsIHllYXIsIGZyZXF1ZW5jeSkgJT4lCiAgbXV0YXRlKHllYXJHID0geWVhciA+IHdvcmQpICU+JQogIGZpbHRlcih5ZWFyRyA9PSBUUlVFKQpobHNwYW5pc2ggPSBvcmlnaW5hbGhsc3BhbmlzaAoKaGxNc3BhbmlzaCA9IG9yaWdpbmFsaGxzcGFuaXNoICU+JSBncm91cF9ieSh3b3JkKSAlPiUgc3VtbWFyaXNlKGZyZXF1ZW5jeSA9IG1heChmcmVxdWVuY3kpKQpobFlzcGFuaXNoID0gb3JpZ2luYWxobHNwYW5pc2ggJT4lIGdyb3VwX2J5KHllYXIpIApobFRzcGFuaXNoID0gbGVmdF9qb2luKGhsTXNwYW5pc2gsIGhsWXNwYW5pc2gsIGJ5ID0gImZyZXF1ZW5jeSIsIHN1ZmZpeCA9IGMoIi54IiwgIi55IikpCmhsVHNwYW5pc2ggPSBzZWxlY3QoaGxUc3BhbmlzaCwgd29yZC54LCB5ZWFyLCBmcmVxdWVuY3kpCmhsVHNwYW5pc2ggPSBobFRzcGFuaXNoICU+JSBncm91cF9ieSh3b3JkLngpICU+JSBmaWx0ZXIgKCEgZHVwbGljYXRlZCh3b3JkLngpKSAlPiUKICByZW5hbWUod29yZCA9IHdvcmQueCkKaGxUMnNwYW5pc2ggPSBobFRzcGFuaXNoICU+JSBzZWxlY3QoZnJlcXVlbmN5KSAlPiUKICBsZWZ0X2pvaW4oaGxzcGFuaXNoLCBobFRzcGFuaXNoLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKGZyZXF1ZW5jeS54ID4gKGZyZXF1ZW5jeS55IC8gMikpICU+JQogIHNlbGVjdCh3b3JkLCBmcmVxdWVuY3kueCwgeWVhcikKCgpobEZzcGFuaXNoID0gbGVmdF9qb2luKGhsVHNwYW5pc2gsIGhsVDJzcGFuaXNoLCBieSA9ICJ3b3JkIikgJT4lCiAgZmlsdGVyKHllYXIueSA+IHllYXIueCkgJT4lCiAgZ3JvdXBfYnkod29yZCkgJT4lIHN1bW1hcmlzZSh5ZWFyLnkgPSBtaW4oeWVhci55KSkKaGxUc3BhbmlzaCA9IGhsVHNwYW5pc2ggJT4lIHNlbGVjdCh3b3JkLCB5ZWFyKQpobEZzcGFuaXNoID0gbGVmdF9qb2luKGhsRnNwYW5pc2gsIGhsVHNwYW5pc2gsIGJ5ID0gIndvcmQiKSAKaGxGc3BhbmlzaCA9IG11dGF0ZShobEZzcGFuaXNoLCBoYWxmX2xpZmUgPSAoeWVhci55IC0geWVhcikpCmhsRnNwYW5pc2ggPSBobEZzcGFuaXNoICU+JSByZW5hbWUobmdyYW1feWVhciA9IHdvcmQpCmhsRnNwYW5pc2ggPSBobEZzcGFuaXNoICU+JSBzZWxlY3QobmdyYW1feWVhciwgaGFsZl9saWZlKQoKc3BhbmlzaGhsID0gZ2dwbG90KGhsRnNwYW5pc2gsIGFlcyh4ID0gbmdyYW1feWVhciwgeSA9IGhhbGZfbGlmZSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gOC8xMCkgKwogIGdlb21fc21vb3RoKCkgKwogIGdndGl0bGUoIlNwYW5pc2giKQpzcGFuaXNoaGwKYGBgCgoKI0kKaSkgQ29tcGFyaW5nIGFjcm9zcyBhbGwgbGFuZ3VhZ2VzLCB3ZXJlIHRoZXJlIGFueSB5ZWFycyB0aGF0IHdlcmUgb3V0bGllcnMsCnN1Y2ggYXMgeWVhcnMgdGhhdCB3ZXJlIGZvcmdvdHRlbiBwYXJ0aWN1bGFybHkgcXVpY2tseSBvciBwYXJ0aWN1bGFybHkKc2xvd2x5PyBCcmllZmx5IHNwZWN1bGF0ZSBhYm91dCBwb3NzaWJsZSByZWFzb25zIGZvciB0aGF0IHBhdHRlcm4uCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJncmlkRXh0cmEiKQpsaWJyYXJ5KCJncmlkRXh0cmEiKQoKZ3JpZC5hcnJhbmdlKGVuZ2xpc2hobCwgY2hpbmVzZWhsLGZyZW5jaGhsLCBnZXJtYW5obCwgaGVicmV3aGwsIGl0YWxpYW5obCwgcnVzc2lhbmhsLCBzcGFuaXNoaGwsIG5yb3cgPSAyKQpgYGAKQWNyb3NzIGFsbCBsYW5ndWFnZXMsIHRoZXJlIGFyZSBvdXRsaWVycyB3aXRoaW4gdGhlIG1pZGRsZSBvZiB0aGUgcmFuZ2Ugb2YgMTg3NS0xOTc1LCBzcGVjaWZpY2FsbHkgdGhlIDFncmFtIDE5MjUsIG15IHNwZWN1bGF0aW9uIHdvdWxkIGJlIHRoYXQgdGhlc2UgYXJlIHllYXJzIHdpdGggaW50ZXJuYXRpb25hbCBldmVudHMgdGhhdCB3ZXJlIHJlY29yZGVkIGluIGVhY2ggbGFuZ3VhZ2UgYW5kIHRoZXJlIHdvdWxkIGJlIGEgaGlnaCBmcmVxdWVuY3kgb2YgdGhlbSB3aXRoIGEgaGlnaCBoYWxmLWxpZmUgZHVlIHRvIHRoZSBpbXBvcnRhbmNlIG9mIHRob3NlIGV2ZW50cyB0aGF0IGhhcHBlbmVkIHdpdGhpbiB0aG9zZSB5ZWFycy4gTG9va2luZyBhdCBIZWJyZXcsIENoaW5lc2UgYW5kIEl0YWxpYW4sIHRoZXkgYm90aCBoYXZlIHRoZWlyIGxhcmdlc3Qgb3V0bGllciBpbiAyIHllYXJzIGNsb3NlIHRvIGVhY2ggb3RoZXIgd2hpY2ggY291bGQgYmUgYSBzaGFyZWQgZXZlbnQgYW1vbmcgdGhlbS4gQ2hpbmEgaGFzIGEgaGlnaGVyIHZhcmlhbmNlIGFyb3VuZCBpdHMgMWdyYW0gaGFsZi1saWZlIGZyZXF1ZW5jeSBvdXQgb2YgZXZlcnkgb3RoZXIgbGFuZ3VhZ2UgYmV0d2VlbiAxODc1LTE5MjUgd2hpY2ggY291bGQgYmUgZHVlIHRvIHNvY2lvcG9saXRpY2FsIGV2ZW50cyB3aXRoaW4gbWFuZGFyaW4vY2FudG9uZXNlIHNwZWFraW5nIGFyZWFzLiA=